﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace RF35Lib
{
    public class RF35Util
    {
        private const byte B0 = 0x00;
        private const byte B1 = 0x00;
        private const byte B2 = 0x00;
        private const byte B3 = 0x01;
        private const byte Bk = 0x00;

        private IntPtr icdev = IntPtr.Zero; //设备号
        private Int16 port;  //端口号
        private Int32 baud;  //波特率
        private bool isOpen = false;
        byte[] snr = new byte[5];
        byte[] devKeyA = new byte[6] { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
        byte[] devKeyB = new byte[6] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

        public System.IntPtr Icdev
        {
            get { return icdev; }
        }

        public short Port
        {
            get { return port; }
            set { port = value; }
        }

        public int Baud
        {
            get { return baud; }
            set { baud = value; }
        }

        public bool IsOpen
        {
            get { return isOpen; }
            set { isOpen = value; }
        }

        public byte[] Snr
        {
            get { return snr; }
            set { snr = value; }
        }

        public byte[] DevKeyA
        {
            get { return devKeyA; }
            set { devKeyA = value; }
        }

        public byte[] DevKeyB
        {
            get { return devKeyB; }
            set { devKeyB = value; }
        }


        public void Open()
        {
            if (!isOpen)
            {
                icdev = RFDLL.rf_init(port, baud);
                if (!icdev.Equals(IntPtr.Zero))
                {
                    RFDLL.rf_beep(icdev, 30);
                    isOpen = true;
                    for (byte sector = 0; sector < 16; sector++)
                    {
                        short st;
                        st = RFDLL.rf_load_key(icdev, PwdMode.KEYA, sector, devKeyA);
                        if (st != 0)
                        {
                            string s1 = Convert.ToString(sector);
                            Console.WriteLine(s1 + " sector rf_load_key error!");
                        }
                    }
                }
            }
        }

        public void Close()
        {
            if (isOpen && !icdev.Equals(IntPtr.Zero))
            {
                RFDLL.rf_exit(icdev);
                isOpen = false;
            }
        }

        private bool RFSelectCard()
        {
           return (RFDLL.rf_card(icdev, SelectMode.ALL, snr) == 0) ? true : false; 
        }

        private bool RFauthentication(byte sector)
        {
            return RFDLL.rf_authentication(icdev, PwdMode.KEYA, sector) == 0 ? true : false;
        }
       
        public byte[] ReadBlockData(byte block)
        {
            short st;
            byte[] databuffer = new byte[32];
            this.RFSelectCard();
            this.RFauthentication(block);
            st = RFDLL.rf_read_hex(icdev, block, databuffer);
            if (st == 0)
            {
                RFDLL.rf_halt(icdev);
                return databuffer;
            }
            RFDLL.rf_halt(icdev);
            return null;
        }

        public bool WriteBlockData(byte block, byte[] data)
        {
            bool flag;
            short st;
            if (data.Length < 16) return false;
            flag= this.RFSelectCard();
            flag= this.RFauthentication((byte)(block/4));
            st = RFDLL.rf_write(icdev, block, data);
            if(st == 0)
            {
                RFDLL.rf_halt(icdev); 
                return true;
            }
            else
            {
                RFDLL.rf_halt(icdev);
                return false;
            }
        }

        /// <summary>
        /// 获得ＩＣ卡序列号
        /// </summary>
        /// <returns></returns>
        public byte[] ReadCardSerialNum()
        {          
            byte[] rs = this.ReadBlockData(0);           
            return rs;
        }

        /// <summary>
        /// 更新卡内某扇区密码
        /// </summary>
        /// <param name="sector">扇区号</param>
        /// <param name="keyA">卡KeyA 密码</param>
        /// <returns></returns>
        public bool UpdateSectorPassword(byte sector,byte[] keyA)
        {
            short st=-1;
            bool rs;
            rs= this.RFSelectCard();
            rs= this.RFauthentication(sector);
            st=RFDLL.rf_changeb3(icdev, sector, keyA, B0, B1, B2, B3, Bk, keyA);
            if (st == 0)
            {
                RFDLL.rf_halt(icdev);
                return true;
            }
            else
            {    
                 RFDLL.rf_halt(icdev);
                return false;
            }
        }

        /// <summary>
        /// 更改16个扇区密码
        /// </summary>
        /// <param name="keyA"></param>
        public void UpdateCardPassword(byte[] keyA)
        {
            for (byte i = 0; i < 16; i++)
            {
                this.UpdateSectorPassword(i, keyA);
            }
        }
    }
}
